Cosenseで任意のページの関連ページ(1 hop link)をランダムに表示するUserScript
Cosenseで任意のページを開いているとき、ページの下部に関連ページのリストが表示されますが、その中の「1 hop link」すなわち、
そのページから直接にリンクしているリンク先のページ
そのページへ直接にリンクしてきているリンク元のページ
をランダム順で表示し続けるUserScriptです。
https://gyazo.com/4a535a3a572a182676f45e90fed9081d
(関連ページリストの中で"Links"という見出しで括られているページ群を、ランダムな順番で表示します)
機能の詳細
ページの右上のページメニューに2個のアイコンが追加されます。
赤矢印のアイコンを1回押すごとに、「最初にそのアイコンを押したページの関連ページ(1 hop link)」に遷移していきます。遷移する順番はランダムです。
例えばCosenseというタイトルのページでこのアイコンを押すと、Cosenseが「対象のキーワード」として指定され、Cosenseというページの関連ページに遷移していきます。
青矢印のアイコンを押すと、「対象のキーワード」がリセットされます。
https://gyazo.com/6c9e27416cf48c522558837c29876957
ランダム順で表示されるのは、ページ下部の「関連ページリスト」の中の"1 hop link"、すなわち、「直接リンクまたは直接被リンクされているページ」です。こちら↓の例で赤枠で囲っているページ群です。
https://gyazo.com/4a535a3a572a182676f45e90fed9081d
("Links"という見出しで括られているページ群がランダム順で表示されます)
「対象のキーワード」が指定されているとき(リセットされていないとき)は、ページの右下に「現在のキーワード」が表示されます。
この文字をクリックすると、そのページ(=最初にアイコンを押したページ)に移動します。
https://gyazo.com/a350e4310df8c7fd7b3e9716796ac9a6
サンプル
Cosenseというタイトルのページで実行したサンプルの動画です(再生すると少し音が出ます)。
https://gyazo.com/33a88e1b3fd33d3979675f7dfcc92918
コード
倉下さんの〈Cosenseで「次のページ」に移動する〉というコンセプトとコードを参考にして、ChatGPTに作らせたコードです。
/help-jp/UserScriptの説明に従って導入し、ブラウザを1回リロードして下さい。
code:script.js
let cachedKeyword = null;
let cachedList = null;
let keywordDisplayElement = null; // 表示用要素の参照
// 関連ページリストを取得
async function getrefPagesList(title) {
const url = https://scrapbox.io/api/pages/${scrapbox.Project.name}/${title};
const response = await fetch(url);
if (!response.ok) throw new Error(${response.status} ${response.statusText});
const json = await response.json();
return json.relatedPages.links1hop;
}
// ページを表示
async function tempPageLink(link) {
await cosense.Page.show(link);
}
// 現在の対象キーワードを画面右下にリンク付きで表示
function displayCurrentKeyword(keyword) {
const projectName = scrapbox.Project.name;
if (!keywordDisplayElement) {
keywordDisplayElement = document.createElement('a');
keywordDisplayElement.style.position = 'fixed';
keywordDisplayElement.style.bottom = '20px';
keywordDisplayElement.style.right = '0px';
keywordDisplayElement.style.background = 'rgba(0, 0, 0, 0.6)';
keywordDisplayElement.style.color = '#fff';
keywordDisplayElement.style.padding = '6px 12px';
keywordDisplayElement.style.borderRadius = '8px';
keywordDisplayElement.style.zIndex = 9999;
keywordDisplayElement.style.fontSize = '14px';
keywordDisplayElement.style.textDecoration = 'none';
keywordDisplayElement.style.cursor = 'pointer';
//keywordDisplayElement.target = '_blank'; // 新しいタブで開く
document.body.appendChild(keywordDisplayElement);
}
const url = https://scrapbox.io/${projectName}/${encodeURIComponent(keyword)};
keywordDisplayElement.href = url;
keywordDisplayElement.textContent = 現在のキーワード: ${keyword};
}
// キーワード表示を消す
function clearKeywordDisplay() {
if (keywordDisplayElement) {
keywordDisplayElement.remove();
keywordDisplayElement = null;
}
}
// ランダムページに移動するメニュー
scrapbox.PageMenu.addMenu({
title: '関連ページをランダム表示', //ボタンのタイトル(変更可能)
image:'https://gyazo.com/b600e46210befe49f75c17eaf59a8bed/raw', //ランダム表示のアイコン(変更可能)
//image:'https://gyazo.com/03f1dd18b68259d82b7a3bc3a3fa39d7/raw', //ランダム表示のアイコン グレー
onClick: async () => {
try {
if (!cachedKeyword || !cachedList) {
const keyword = cosense.Page.title;
if (!keyword || keyword.trim() === '') return;
cachedKeyword = keyword;
cachedList = await getrefPagesList(encodeURIComponent(keyword));
if (!cachedList || cachedList.length === 0) {
cachedKeyword = null;
cachedList = null;
alert(「${keyword}」の関連ページが見つかりませんでした。);
return;
}
displayCurrentKeyword(keyword);
}
const candidates = cachedList.filter(p => p.title !== cosense.Page.title);
if (candidates.length === 0) {
alert('遷移できるページがありません。');
return;
}
const randomPage = candidatesMath.floor(Math.random() * candidates.length);
tempPageLink(randomPage.title);
} catch (e) {
alert('エラーが発生しました: ' + e.message);
}
}
});
// キーワードをリセットするメニュー
scrapbox.PageMenu.addMenu({
image: 'https://gyazo.com/23bee7339d869111c2e13d7873aac878/raw', //Backspaceのアイコン(変更可能)
//image:'https://gyazo.com/6df821484c3463804a9286a118a0bf85/raw', //Backspaceのアイコン グレー
title: 'キーワードリセット', //ボタンのタイトル(変更可能)
onClick: () => {
cachedKeyword = null;
cachedList = null;
clearKeywordDisplay();
alert('キーワードをリセットしました。');
}
});
更新履歴
2025-07-02:公開